﻿using System;
using System.Web.UI;
using Microsoft.IdentityModel.Claims;
using Microsoft.IdentityModel.Configuration;
using Microsoft.IdentityModel.Protocols.WSFederation;
using Microsoft.IdentityModel.Protocols.WSTrust;
using Microsoft.IdentityModel.Services.SecurityTokenService;
using Veracruz.Facebook.IdentityModel;

namespace Veracruz.IdentityModel.Facebook
{
    // TODO : Use the idfx:FederatedPassiveTokenService 
    public partial class _Default : System.Web.UI.Page
    {
        #region props

        /// <summary>
        /// Returns whether the user is authenticated or not. 
        /// </summary>
        private bool IsAuthenticatedUser
        {
            get
            {
                return ((Page.User) != null && (Page.User.Identity) != null && (Page.User.Identity.IsAuthenticated));
            }
        }

        #endregion
        #region methods

        private SignInResponseMessage ProcessSignInRequest(SignInRequestMessage requestMessage)
        {
            // Ensure that the requestMessage has the required wtrealm parameter
            if (String.IsNullOrEmpty(requestMessage.Realm))
            {
                throw new InvalidOperationException("Missing realm");
            }

            SecurityTokenServiceConfiguration stsconfig = new FacebookSecurityTokenServiceConfiguration();

            // Create our STS backend
            SecurityTokenService sts = new FacebookSecurityTokenService(stsconfig);

            // Create the WS-Federation serializer to process the request and create the response
            WSFederationSerializer federationSerializer = new WSFederationSerializer();

            // Create RST from the request
            RequestSecurityToken request = federationSerializer.CreateRequest(requestMessage, new WSTrustSerializationContext());

            // Get RSTR from our STS backend
            RequestSecurityTokenResponse response = sts.Issue(ClaimsPrincipal.Current, request);



            // Create Response message from the RSTR
            return new SignInResponseMessage(new Uri(response.ReplyTo),
                    federationSerializer.GetResponseAsString(response, new WSTrustSerializationContext()));

        }
        /// <summary>
        /// We perform WS-Federation passive protocol logic in this method and call out to the appropriate request handlers. 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_PreRender(object sender, EventArgs e)
        {
            string l_realm = Request[WSFederationConstants.Parameters.Realm];
            string l_action = Request[WSFederationConstants.Parameters.Action];

            // wsa is a required parameter?
            if (!String.IsNullOrEmpty(l_action))
            {
                // wsa is present. 
                if (l_action == WSFederationConstants.Actions.SignIn)
                {
                    // Use the WSFederationMessage.CreateFromUri to parse the request and create a SignInRequestMessage object.
                    SignInRequestMessage requestMessage = (SignInRequestMessage)WSFederationMessage.CreateFromUri(Request.Url);
                    if (IsAuthenticatedUser)
                    {
                        // Process the sign in request. 
                        SignInResponseMessage responseMessage = ProcessSignInRequest(requestMessage);
                        // Write the response message. 

                        responseMessage.Context = requestMessage.Context;

                        responseMessage.Write(Page.Response.Output);

                        Response.Flush();
                        Response.End();
                    }

                }
                else if (l_action == WSFederationConstants.Actions.SignOut || l_action == WSFederationConstants.Actions.SignOutCleanup)
                {
                    // Perform any sign-out clean-up operations here
                }
                else
                {
                    throw new InvalidOperationException("Invalid Action");
                }
            }
        }

        #endregion
    }
}
